﻿using System.Collections.Generic;
using System.Reflection;
using UnityEditor;
using UnityEditor.IMGUI.Controls;
using UnityEngine;

namespace XUBadWord
{
    namespace Editor
    {
        internal class XUBadWordWindow : EditorWindow
        {
            [MenuItem("XUPK/XUBadWord/Runtime", false, 1)]
            public static void SetConfig()
            {
                EditorWindow window = GetWindow<XUBadWordWindow>("BadWord");
                window.minSize = window.maxSize = new Vector2(400, 600);
                window.Show();
            }

            private void OnGUI()
            {
                XUBadWordRuntime.OnGUI();
            }
        }

        internal class XUBadWordRuntime
        {
            private static WordDatabase wordDatabase;

            private static TreeViewState wordTreeViewState;
            private static WordTreeView wordTreeView;
            private static SearchField wordSearchField;

            public static void OnGUI()
            {
                GUILayout.BeginHorizontal();
                {
                    GUILayout.BeginVertical("box");
                    {
                        if (wordDatabase == null || GUILayout.Button("内存快照", GUILayout.Height(20)))
                        {
                            wordDatabase = new WordDatabase();
                            wordTreeView = null;
                        }

                        if (wordTreeView == null)
                        {
                            if (wordTreeViewState == null)
                            {
                                wordTreeViewState = new TreeViewState();
                            }
                            wordTreeView = new WordTreeView(wordTreeViewState);
                        }

                        if (wordSearchField == null)
                        {
                            wordSearchField = new SearchField();
                            wordSearchField.downOrUpArrowKeyPressed += wordTreeView.SetFocusAndEnsureSelectedItem;
                        }

                        GUILayout.BeginHorizontal();
                        GUILayout.Space(15);
                        wordTreeView.searchString = wordSearchField.OnToolbarGUI(wordTreeView.searchString);
                        GUILayout.EndHorizontal();

                        GUILayout.Space(3);

                        wordTreeView.OnGUI(GUILayoutUtility.GetRect(0, 100000, 0, 100000));
                    }
                    GUILayout.EndVertical();
                }
                GUILayout.EndHorizontal();
            }

            //==========================================================================================

            private class WordDatabase
            {
                public Dictionary<char, Dictionary<string, int>> nodeMap = new Dictionary<char, Dictionary<string, int>>();

                public WordDatabase()
                {
                    nodeMap = XUBadWordMgr.GetInstance().GetType().GetField("nodeMap", BindingFlags.NonPublic | BindingFlags.Instance).GetValue(XUBadWordMgr.GetInstance()) as Dictionary<char, Dictionary<string, int>>;
                }
            }

            //==========================================================================================

            private class WordTreeView : TreeView
            {
                private TreeViewItem root = new TreeViewItem { id = 0, depth = -1, displayName = "Root" };
                private List<TreeViewItem> treeItems = new List<TreeViewItem>();
                private List<TreeViewItem> allItems = new List<TreeViewItem>();

                private int itemIndex = 1;

                public WordTreeView(TreeViewState treeViewState)
                    : base(treeViewState)
                {
                    foreach (var node in wordDatabase.nodeMap)
                    {
                        TreeViewItem item = new TreeViewItem
                        {
                            id = itemIndex++,
                            depth = 0,
                            displayName = node.Key.ToString(),
                        };
                        allItems.Add(item);
                        foreach (var subNode in node.Value)
                        {
                            TreeViewItem subItem = new TreeViewItem
                            {
                                id = itemIndex++,
                                depth = 1,
                                displayName = subNode.Key,
                            };
                            allItems.Add(subItem);
                            item.AddChild(subItem);
                        }
                        treeItems.Add(item);
                    }

                    Reload();

                    if (treeItems.Count > 0)
                    {
                        SetSelectWord(treeItems[0].displayName);
                    }
                }

                protected override TreeViewItem BuildRoot()
                {
                    SetupParentsAndChildrenFromDepths(root, treeItems);
                    return root;
                }

                protected override bool CanMultiSelect(TreeViewItem item)
                {
                    return false;
                }

                //=============================================================

                public void SetSelectWord(string word)
                {
                    foreach (var item in allItems)
                    {
                        if (item.displayName.Equals(word))
                        {
                            SetSelection(new List<int>() { item.id });
                            SingleClickedItem(item.id);
                            break;
                        }
                    }
                }
            }
        }
    }
}